{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Rainbow: Combining Improvements in Deep Reinforcement Learning"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Imports"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import gym\n",
    "import numpy as np\n",
    "\n",
    "import torch\n",
    "import torch.optim as optim\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "\n",
    "from IPython.display import clear_output\n",
    "from matplotlib import pyplot as plt\n",
    "%matplotlib inline\n",
    "\n",
    "from timeit import default_timer as timer\n",
    "from datetime import timedelta\n",
    "import math\n",
    "\n",
    "from utils.wrappers import *\n",
    "from utils.ReplayMemory import PrioritizedReplayMemory\n",
    "from networks.layers import NoisyLinear\n",
    "from agents.DQN import Model as DQN_Agent\n",
    "\n",
    "from utils.hyperparameters import Config"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Hyperparameters"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "config = Config()\n",
    "\n",
    "config.device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n",
    "\n",
    "#Multi-step returns\n",
    "config.N_STEPS = 3\n",
    "\n",
    "#misc agent variables\n",
    "config.GAMMA=0.99\n",
    "config.LR=1e-4\n",
    "\n",
    "#memory\n",
    "config.TARGET_NET_UPDATE_FREQ = 1000\n",
    "config.EXP_REPLAY_SIZE = 100000\n",
    "config.BATCH_SIZE = 32\n",
    "config.PRIORITY_ALPHA=0.6\n",
    "config.PRIORITY_BETA_START=0.4\n",
    "config.PRIORITY_BETA_FRAMES = 100000\n",
    "\n",
    "#epsilon variables\n",
    "config.SIGMA_INIT=0.5\n",
    "\n",
    "#Learning control variables\n",
    "config.LEARN_START = 10000\n",
    "config.MAX_FRAMES=700000\n",
    "\n",
    "#Categorical Params\n",
    "config.ATOMS = 51\n",
    "config.V_MAX = 10\n",
    "config.V_MIN = -10"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Network"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "class CategoricalDuelingDQN(nn.Module):\n",
    "    def __init__(self, input_shape, num_actions, sigma_init=0.5, atoms=51):\n",
    "        super(CategoricalDuelingDQN, self).__init__()\n",
    "        \n",
    "        self.input_shape = input_shape\n",
    "        self.num_actions = num_actions\n",
    "        self.atoms = atoms\n",
    "\n",
    "        self.conv1 = nn.Conv2d(self.input_shape[0], 32, kernel_size=8, stride=4)\n",
    "        self.conv2 = nn.Conv2d(32, 64, kernel_size=4, stride=2)\n",
    "        self.conv3 = nn.Conv2d(64, 64, kernel_size=3, stride=1)\n",
    "\n",
    "        self.adv1 = NoisyLinear(self.feature_size(), 512, sigma_init)\n",
    "        self.adv2 = NoisyLinear(512, self.num_actions*self.atoms, sigma_init)\n",
    "\n",
    "        self.val1 = NoisyLinear(self.feature_size(), 512, sigma_init)\n",
    "        self.val2 = NoisyLinear(512, 1*self.atoms, sigma_init)\n",
    "        \n",
    "    def forward(self, x):\n",
    "        x = F.relu(self.conv1(x))\n",
    "        x = F.relu(self.conv2(x))\n",
    "        x = F.relu(self.conv3(x))\n",
    "        x = x.view(x.size(0), -1)\n",
    "        adv = F.relu(self.adv1(x))\n",
    "        adv = self.adv2(adv).view(-1, self.num_actions, self.atoms)\n",
    "\n",
    "        val = F.relu(self.val1(x))\n",
    "        val = self.val2(val).view(-1, 1, self.atoms)\n",
    "\n",
    "        final = val + adv - adv.mean(dim=1).view(-1, 1, self.atoms)\n",
    "\n",
    "        return F.softmax(final, dim=2)\n",
    "    \n",
    "    def feature_size(self):\n",
    "        return self.conv3(self.conv2(self.conv1(torch.zeros(1, *self.input_shape)))).view(1, -1).size(1)\n",
    "\n",
    "    def sample_noise(self):\n",
    "        self.adv1.sample_noise()\n",
    "        self.adv2.sample_noise()\n",
    "        self.val1.sample_noise()\n",
    "        self.val2.sample_noise()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Agent"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Model(DQN_Agent):\n",
    "    def __init__(self, static_policy=False, env=None, config=None):\n",
    "        self.atoms=config.ATOMS\n",
    "        self.v_max=config.V_MAX\n",
    "        self.v_min=config.V_MIN\n",
    "        self.supports = torch.linspace(self.v_min, self.v_max, self.atoms).view(1, 1, self.atoms).to(config.device)\n",
    "        self.delta = (self.v_max - self.v_min) / (self.atoms - 1)\n",
    "\n",
    "        super(Model, self).__init__(static_policy, env, config)\n",
    "\n",
    "        self.nsteps=max(self.nsteps,3)\n",
    "    \n",
    "    def declare_networks(self):\n",
    "        self.model = CategoricalDuelingDQN(self.num_feats, self.num_actions, sigma_init=self.sigma_init, atoms=self.atoms)\n",
    "        self.target_model = CategoricalDuelingDQN(self.num_feats, self.num_actions, sigma_init=self.sigma_init, atoms=self.atoms)\n",
    "        \n",
    "    def declare_memory(self):\n",
    "        self.memory = PrioritizedReplayMemory(self.experience_replay_size, self.priority_alpha, self.priority_beta_start, self.priority_beta_frames)\n",
    "        \n",
    "    def projection_distribution(self, batch_vars):\n",
    "        batch_state, batch_action, batch_reward, non_final_next_states, non_final_mask, empty_next_state_values, indices, weights = batch_vars\n",
    "\n",
    "        with torch.no_grad():\n",
    "            max_next_dist = torch.zeros((self.batch_size, 1, self.atoms), device=self.device, dtype=torch.float) + 1./self.atoms\n",
    "            if not empty_next_state_values:\n",
    "                max_next_action = self.get_max_next_state_action(non_final_next_states)\n",
    "                self.target_model.sample_noise()\n",
    "                max_next_dist[non_final_mask] = self.target_model(non_final_next_states).gather(1, max_next_action)\n",
    "                max_next_dist = max_next_dist.squeeze()\n",
    "\n",
    "\n",
    "            Tz = batch_reward.view(-1, 1) + (self.gamma**self.nsteps)*self.supports.view(1, -1) * non_final_mask.to(torch.float).view(-1, 1)\n",
    "            Tz = Tz.clamp(self.v_min, self.v_max)\n",
    "            b = (Tz - self.v_min) / self.delta\n",
    "            l = b.floor().to(torch.int64)\n",
    "            u = b.ceil().to(torch.int64)\n",
    "            l[(u > 0) * (l == u)] -= 1\n",
    "            u[(l < (self.atoms - 1)) * (l == u)] += 1\n",
    "            \n",
    "\n",
    "            offset = torch.linspace(0, (self.batch_size - 1) * self.atoms, self.batch_size).unsqueeze(dim=1).expand(self.batch_size, self.atoms).to(batch_action)\n",
    "            m = batch_state.new_zeros(self.batch_size, self.atoms)\n",
    "            m.view(-1).index_add_(0, (l + offset).view(-1), (max_next_dist * (u.float() - b)).view(-1))  # m_l = m_l + p(s_t+n, a*)(u - b)\n",
    "            m.view(-1).index_add_(0, (u + offset).view(-1), (max_next_dist * (b - l.float())).view(-1))  # m_u = m_u + p(s_t+n, a*)(b - l)\n",
    "\n",
    "        return m\n",
    "    \n",
    "    def compute_loss(self, batch_vars):\n",
    "        batch_state, batch_action, batch_reward, non_final_next_states, non_final_mask, empty_next_state_values, indices, weights = batch_vars\n",
    "\n",
    "        batch_action = batch_action.unsqueeze(dim=-1).expand(-1, -1, self.atoms)\n",
    "        batch_reward = batch_reward.view(-1, 1, 1)\n",
    "\n",
    "        #estimate\n",
    "        self.model.sample_noise()\n",
    "        current_dist = self.model(batch_state).gather(1, batch_action).squeeze()\n",
    "\n",
    "        target_prob = self.projection_distribution(batch_vars)\n",
    "          \n",
    "        loss = -(target_prob * current_dist.log()).sum(-1)\n",
    "        self.memory.update_priorities(indices, loss.detach().squeeze().abs().cpu().numpy().tolist())\n",
    "        loss = loss * weights\n",
    "        loss = loss.mean()\n",
    "\n",
    "        return loss\n",
    "    \n",
    "    def get_action(self, s):\n",
    "        with torch.no_grad():\n",
    "            X = torch.tensor([s], device=self.device, dtype=torch.float)\n",
    "            self.model.sample_noise()\n",
    "            a = self.model(X) * self.supports\n",
    "            a = a.sum(dim=2).max(1)[1].view(1, 1)\n",
    "            return a.item()\n",
    "            \n",
    "    def get_max_next_state_action(self, next_states):\n",
    "        next_dist = self.model(next_states) * self.supports\n",
    "        return next_dist.sum(dim=2).max(1)[1].view(next_states.size(0), 1, 1).expand(-1, -1, self.atoms)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Plot Results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot(frame_idx, rewards, losses, sigma, elapsed_time):\n",
    "    clear_output(True)\n",
    "    plt.figure(figsize=(20,5))\n",
    "    plt.subplot(131)\n",
    "    plt.title('frame %s. reward: %s. time: %s' % (frame_idx, np.mean(rewards[-10:]), elapsed_time))\n",
    "    plt.plot(rewards)\n",
    "    if losses:\n",
    "        plt.subplot(132)\n",
    "        plt.title('loss')\n",
    "        plt.plot(losses)\n",
    "    if sigma:\n",
    "        plt.subplot(133)\n",
    "        plt.title('noisy param magnitude')\n",
    "        plt.plot(sigma)\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Training Loop"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1440x360 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "start=timer()\n",
    "\n",
    "env_id = \"PongNoFrameskip-v4\"\n",
    "env    = make_atari(env_id)\n",
    "env    = wrap_deepmind(env, frame_stack=False)\n",
    "env    = wrap_pytorch(env)\n",
    "model = Model(env=env, config=config)\n",
    "\n",
    "episode_reward = 0\n",
    "\n",
    "observation = env.reset()\n",
    "for frame_idx in range(1, config.MAX_FRAMES + 1):\n",
    "    action = model.get_action(observation)\n",
    "    prev_observation=observation\n",
    "    observation, reward, done, _ = env.step(action)\n",
    "    observation = None if done else observation\n",
    "\n",
    "    model.update(prev_observation, action, reward, observation, frame_idx)\n",
    "    episode_reward += reward\n",
    "\n",
    "    if done:\n",
    "        model.finish_nstep()\n",
    "        model.reset_hx()\n",
    "        observation = env.reset()\n",
    "        model.save_reward(episode_reward)\n",
    "        episode_reward = 0\n",
    "        \n",
    "        if np.mean(model.rewards[-10:]) > 19:\n",
    "            plot(frame_idx, model.rewards, model.losses, model.sigma_parameter_mag, timedelta(seconds=int(timer()-start)))\n",
    "            break\n",
    "\n",
    "    if frame_idx % 10000 == 0:\n",
    "        plot(frame_idx, model.rewards, model.losses, model.sigma_parameter_mag, timedelta(seconds=int(timer()-start)))\n",
    "\n",
    "model.save_w()\n",
    "env.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
